/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-08-28     chenbin       the first version
 */
#include <rtthread.h>
#include "app_tm16xx.h"
#include "drv_tm16xx.h"


const uint8_t  bitmap_8x16[] =
{

    /* 0 */
    0x7c,  //.@@@@@.
    0x46,  //.@...@@
    0xc2,  //@@....@
    0x82,  //@.....@
    0x82,  //@.....@
    0x82,  //@.....@
    0x82,  //@.....@
    0x82,  //@.....@
    0xc2,  //@@....@
    0x46,  //.@...@@
    0x7c,  //.@@@@@.
    0x00, 0x00, 0x00, 0x00, 0x00,


    /* 1 */
    0xf0,  //@@@@
    0xb0,  //@.@@
    0x30,  //..@@
    0x30,  //..@@
    0x30,  //..@@
    0x30,  //..@@
    0x30,  //..@@
    0x30,  //..@@
    0x30,  //..@@
    0x30,  //..@@
    0x30,  //..@@
    0x00, 0x00, 0x00, 0x00, 0x00,

    /* 2 */
    0x7c,  //.@@@@@.
    0x06,  //.....@@
    0x06,  //.....@@
    0x06,  //.....@@
    0x04,  //.....@.
    0x0c,  //....@@.
    0x18,  //...@@..
    0x30,  //..@@...
    0x60,  //.@@....
    0xc0,  //@@.....
    0xfe,  //@@@@@@@
    0x00,   0x00,    0x00,    0x00,    0x00,


    /* 3 */
    0x7c,  //.@@@@@.
    0x04,  //.....@.
    0x06,  //.....@@
    0x04,  //.....@.
    0x0c,  //....@@.
    0x78,  //.@@@@..
    0x06,  //.....@@
    0x06,  //.....@@
    0x06,  //.....@@
    0x06,  //.....@@
    0xfc,  //@@@@@@.
    0x00,    0x00,    0x00,    0x00,    0x00,

    /* 4 */
    0x0c,  //....@@.
    0x1c,  //...@@@.
    0x14,  //...@.@.
    0x24,  //..@..@.
    0x64,  //.@@..@.
    0xc4,  //@@...@.
    0x84,  //@....@.
    0xfe,  //@@@@@@@
    0x04,  //.....@.
    0x04,  //.....@.
    0x04,  //.....@.
    0x00,    0x00,    0x00,    0x00,    0x00,

    /* 5 */
    0x7c,  //.@@@@@.
    0x40,  //.@.....
    0x40,  //.@.....
    0x40,  //.@.....
    0x78,  //.@@@@..
    0x86,  //@....@@
    0x02,  //......@
    0x02,  //......@
    0x02,  //......@
    0x06,  //.....@@
    0xfc,  //@@@@@@.
    0x00,    0x00,    0x00,    0x00,    0x00,

    /* 6 */
    0x1c,  //...@@@.
    0x60,  //.@@....
    0x40,  //.@.....
    0xc0,  //@@.....
    0xbc,  //@.@@@@.
    0xc6,  //@@...@@
    0x82,  //@.....@
    0x82,  //@.....@
    0x82,  //@.....@
    0xc6,  //@@...@@
    0x7c,  //.@@@@@.
    0x00,    0x00,    0x00,    0x00,    0x00,

    /* 7 */
    0xfe,  //@@@@@@@
    0x02,  //......@
    0x06,  //.....@@
    0x04,  //.....@.
    0x0c,  //....@@.
    0x08,  //....@..
    0x18,  //...@@..
    0x10,  //...@...
    0x30,  //..@@...
    0x20,  //..@....
    0x60,  //.@@....
    0x00,    0x00,    0x00,    0x00,    0x00,


    /* 8 */
    0x7c,  //.@@@@@.
    0xc6,  //@@...@@
    0x82,  //@.....@
    0xc2,  //@@....@
    0x44,  //.@...@.
    0x7c,  //.@@@@@.
    0xc2,  //@@....@
    0x82,  //@.....@
    0x82,  //@.....@
    0xc6,  //@@...@@
    0x7c,  //.@@@@@.
    0x00,    0x00,    0x00,    0x00,    0x00,


    /* 9 */
    0x7c,  //.@@@@@.
    0xc6,  //@@...@@
    0x82,  //@.....@
    0x82,  //@.....@
    0x82,  //@.....@
    0xc6,  //@@...@@
    0x7a,  //.@@@@.@
    0x06,  //.....@@
    0x04,  //.....@.
    0x0c,  //....@@.
    0x70,  //.@@@...
    0x00,    0x00,    0x00,    0x00,    0x00,
};

//static const uint8_t seg_table_yang[] = {
//    0xc0,  //0
//    0xf9,  //1
//    0xa4,  //2
//    0xb0,  //3
//    0x99,  //4
//    0x92,  //5
//    0x82,  //6
//    0xf8,  //7
//    0x80,  //8
//    0x90,  //9
//    0x88,  //A
//    0x83,  //B
//    0xc6,  //C
//    0xa1,  //D
//    0x86,  //E
//    0x8e,  //F
//};

static const uint8_t seg_table_ying[] = {
    0x3F,  //"0"
    0x06,  //"1"
    0x5B,  //"2"
    0x4F,  //"3"
    0x66,  //"4"
    0x6D,  //"5"
    0x7D,  //"6"
    0x07,  //"7"
    0x7F,  //"8"
    0x6F,  //"9"
    0x77,  //"A"
    0x7C,  //"B"
    0x39,  //"C"
    0x5E,  //"D"
    0x79,  //"E"
    0x71,  //"F"
    0x76,  //"H"
    0x38,  //"L"
};

static uint8_t display_buff[16]= {0};

void app_smg_show_num(uint8_t index, uint8_t num_val)
{
    display_buff[index*2] &= (0x80);
    if(num_val <= 0X0F)
    {
        display_buff[index*2] |=  (0x7F & seg_table_ying[num_val]);
    }
}

void app_smg_show_led(uint8_t led_mask,uint8_t led_bit)
{
    if(led_mask & 0x01)
    {
        if(led_bit & 0x01)
        {
            display_buff[1] |= 0x01;
        }else {
            display_buff[1] &= ~0x01;
        }
    }
    if(led_mask & 0x02)
    {
        if(led_bit & 0x02)
        {
            display_buff[3] |= 0x01;
        }else {
            display_buff[3] &= ~0x01;
        }
    }
    if(led_mask & 0x04)
    {
        if(led_bit & 0x04)
        {
            display_buff[5] |= 0x01;
        }else {
            display_buff[5] &= ~0x01;
        }
    }
    if(led_mask & 0x08)
    {
        if(led_bit & 0x08)
        {
            display_buff[7] |= 0x01;
        }else {
            display_buff[7] &= ~0x01;
        }
    }
    if(led_mask & 0x10)
    {
        if(led_bit & 0x10)
        {
            display_buff[9] |= 0x01;
        }else {
            display_buff[9] &= ~0x01;
        }
    }
    if(led_mask & 0x20)
    {
        if(led_bit & 0x20)
        {
            display_buff[11] |= 0x01;
        }else {
            display_buff[11] &= ~0x01;
        }
    }
    if(led_mask & 0x40)
    {
        if(led_bit & 0x40)
        {
            display_buff[13] |= 0x01;
        }else {
            display_buff[13] &= ~0x01;
        }
    }
    if(led_mask & 0x80)
    {
        if(led_bit & 0x80)
        {
            display_buff[15] |= 0x01;
        }else {
            display_buff[15] &= ~0x01;
        }
    }
}

void app_smg_refresh(void)
{
    tm1668_display(0, display_buff,16);
}

void tm1668_show_loop(void)
{
    uint32_t num = rt_tick_get();
    uint8_t key_val[4] = {0};
    uint8_t led_val = 0;

    rt_kprintf("tm1668 init\n");

    for(int i=0;i< 8;i++)
    {
        app_smg_show_num(i, 8);
    }
    app_smg_show_led(0xFF,0xFF);
    app_smg_refresh();

    while(1)
    {
        rt_thread_mdelay(20);
        tm1668_readkey(key_val, 4);

        led_val = 0;
        led_val |= (key_val[0]&0x01)?0x01:0x00;
        led_val |= (key_val[1]&0x01)?0x02:0x00;
        led_val |= (key_val[2]&0x01)?0x04:0x00;
        led_val |= (key_val[3]&0x01)?0x08:0x00;

        led_val |= (key_val[0]&0x10)?0x10:0x00;
        led_val |= (key_val[1]&0x10)?0x20:0x00;
        led_val |= (key_val[2]&0x10)?0x40:0x00;
        led_val |= (key_val[3]&0x10)?0x80:0x00;

        app_smg_show_led(0xFF,led_val);

        num = rt_tick_get() / 10;

        app_smg_show_num(0, (num/10000000)%10);
        app_smg_show_num(1, (num/1000000)%10);
        app_smg_show_num(2, (num/100000)%10);
        app_smg_show_num(3, (num/10000)%10);

        app_smg_show_num(4, (num/1000)%10);
        app_smg_show_num(5, (num/100)%10);
        app_smg_show_num(6, (num/10)%10);
        app_smg_show_num(7, num%10);
        app_smg_refresh();
    }
}


int lcd_buffer_get_bit(const uint8_t *array,uint16_t index)
{
    uint8_t offset_bit = (index & 0x07); //(index%8);  //
    uint8_t offset_arr = (index >> 0x03); //(index/8);  //
    return (array[offset_arr] & (0x01 << offset_bit))?1:0;
}

void lcd_buffer_set_bit(uint8_t *array,uint16_t index,int status)
{
    uint8_t offset_bit = (index & 0x07); //(index%8);  //
    uint8_t offset_arr = (index >> 0x03); //(index/8);  //
    if(status)
    {
        array[offset_arr] |= (0x01 << offset_bit);
    }else
    {
        array[offset_arr] &= ~(0x01 << offset_bit);
    }
}

void tmxx_buffer_set_bit(uint8_t *array,uint16_t index,int status)
{
    uint8_t offset_bit = (index & 0x07); //(index%8);  //
    uint8_t offset_arr = (index >> 0x03); //(index/8);  //
    if(status)
    {
        array[offset_arr] |= (0x01 << offset_bit);
    }else
    {
        array[offset_arr] &= ~(0x01 << offset_bit);
    }
}

#include "lv_font.h"

LV_FONT_DECLARE(myfont8x)
LV_FONT_DECLARE(myFont)


void lv_font_show_char(const lv_font_t *pfont, lv_font_glyph_dsc_t *pfont_dsc, uint16_t unicode)
{
    const uint8_t *         font_bitmap = NULL;
    uint8_t lcd_temp = 0;
    uint8_t lcd_temp2 = 0;
    uint8_t lcd_buffer[64] = {0};
    if(lv_font_get_glyph_dsc(pfont, pfont_dsc, unicode, '\0') )
    {
        rt_memset(lcd_buffer, 0, 16);
        font_bitmap = lv_font_get_glyph_bitmap(pfont, unicode);
//        rt_kprintf("char: %d info adv_w:%d box_w:%d box_h:%d  %d %d\n", unicode,
//                pfont_dsc->adv_w, pfont_dsc->box_w, pfont_dsc->box_h, pfont_dsc->ofs_x, pfont_dsc->ofs_y);

        for(uint8_t index_h = 0; index_h < pfont_dsc->box_h;index_h++)
        {
            for(uint8_t index_w = 0; index_w < pfont_dsc->box_w; index_w++)
            {
                if(index_w < 8)
                {
                    lcd_buffer_set_bit(lcd_buffer, (8 * index_h)+ index_w,
                            lcd_buffer_get_bit(font_bitmap, (pfont_dsc->box_w * index_h) + index_w ) );
                }
//                    if(lcd_buffer_get_bit(font_bitmap, (pfont_dsc->adv_w * index_h) + index_w ) > 0)
//                    {
//                        lcd_buffer[index_h] |=  (0x01 << index_w);
//                    }

            }
        }

//        lcd_temp = pfont_dsc->box_h * pfont_dsc->box_w;
//        lcd_temp2 = (lcd_temp / 8) + ((lcd_temp%8)?1:0);
//        rt_kprintf("bitmap[%d] ",lcd_temp2);
//        for(uint8_t index = 0; index < lcd_temp2;index++)
//        {
//            rt_kprintf("0x%02X ",font_bitmap[index]);
//            //lcd_buffer[index] = font_bitmap[index];
//        }
//        rt_kprintf("\n");

        rt_memset(display_buff, 0, 16);
        for(uint8_t index = 0; index < 8;index++)
        {
            lcd_temp = lcd_buffer[index];
            if(lcd_temp & (0x01 << 7))
            {
                display_buff[0] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 6))
            {
                display_buff[2] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 5))
            {
                display_buff[4] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 4))
            {
                display_buff[6] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 3))
            {
                display_buff[8] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 2))
            {
                display_buff[10] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 1))
            {
                display_buff[12] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 0))
            {
                display_buff[14] |=  (0x01 << index);
            }
        }
        for(uint8_t index = 0; index < 8;index++)
        {
            lcd_temp = lcd_buffer[8 + index];
            if(lcd_temp & (0x01 << 7))
            {
                display_buff[1] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 6))
            {
                display_buff[3] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 5))
            {
                display_buff[5] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 4))
            {
                display_buff[7] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 3))
            {
                display_buff[9] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 2))
            {
                display_buff[11] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 1))
            {
                display_buff[13] |=  (0x01 << index);
            }
            if(lcd_temp & (0x01 << 0))
            {
                display_buff[15] |=  (0x01 << index);
            }
        }
        app_smg_refresh();
    }
}


void tm1629_show_loop(void)
{
    uint32_t                pos = 0;
    const lv_font_t *       pfont = NULL;
    lv_font_glyph_dsc_t     font_dsc = {0};


    char font_char[16] = "6666";

    rt_kprintf("tm1629 init\n");

    pfont = &myFont;
    //pfont = &lv_font_unscii_16;
    //pfont = &lv_font_unscii_8;

    lv_font_show_char(pfont, &font_dsc, 0x4e2d);
    rt_thread_mdelay(1000);
    lv_font_show_char(pfont, &font_dsc, 0x56fd);
    rt_thread_mdelay(1000);
    while(1)
    {
//        rt_thread_mdelay(10);
//        pos++;
//        pos%= (16*8);
//        for(uint8_t index = 0; index <16;index++)
//        {
//            if(index == (pos/8))
//            {
//                display_buff[index] =  (0x01 << (pos%8));
//            }else {
//                display_buff[index] = 0x00;
//            }
//        }
        rt_thread_mdelay(1000);


        rt_snprintf(font_char,16, "%d", pos);
        lv_font_show_char(pfont, &font_dsc, font_char[0]);
        pos++;
        pos%= 10;
    }
}

void app_tm1668_init(void)
{
    drv_tm1668_init();

    tm1629_show_loop();
    //tm1668_show_loop();
}


